package cn.com.heaton.bleLib.logic.command;

import cn.com.heaton.bleLib.R;
import cn.com.heaton.bleLib.ble.L;
import cn.com.heaton.bleLib.logic.HexUtil;
import cn.com.heaton.bleLib.logic.Rc4;

/**
 * 设备命令
 */
public abstract class Command {

    protected String TAG = getClass().getSimpleName();

    public static byte[] FRAME_HEADER_CODE = {(byte) 0xFA, (byte) 0x05};//头码，fa,05
    public static final int MAX_DATA_LENGTH = 20;//最大数据长度
    public static final int DATA_HEADER_LENGTH = FRAME_HEADER_CODE.length;//数据头长度（frameHeader）

    //指令定义
    //Lora内外置设置
    public static final byte Cmd_Lora_In_Out = 0x03;
    //施工开门命令
    public static final byte Cmd_Open_Door_In = 0x04;
    //获取设备时间
    public static final byte Cmd_Fetch_Time = 0x07;
    //获取设备信息
    public static final byte Cmd_Fetch_Device_Info = 0x08;
    //读取设备参数
    public static final byte Cmd_Getch_Device_Param = 0x09;
    //读取设备白名单记录，根据索引查具体的某一条记录
    public static final byte Cmd_Read_White = 0x0b;
    //读取设备黑名单记录，根据索引查具体的某一条记录
    public static final byte Cmd_Read_Black = 0x0D;
    //读取开门记录
    public static final byte Cmd_Read_Record = 0x0F;
    //读取设备版本号
    public static final byte Cmd_Read_Version = 0x10;
    //设置设备时间
    public static final byte Cmd_Set_Time = 0x11;

    /**
     * 时间格式
     */
    protected static final String FORMAT = "yyyyMMddHHmmss";

    protected abstract boolean execute();

    /**
     * 拼装发送数据
     *
     * @param data
     * @param size
     * @return
     */
    protected static byte[] combineData(byte[] data, int size) {

        //数据总长度,不包括帧头（数据长度，校验和，帧编号）
        int length = size + 3;
//        if (length > MAX_DATA_LENGTH - DATA_HEADER_LENGTH) {
//            return null;
//        }
        int sendLen;
        //发送数据总长度 ， 数据长度 +  协议头的长度
        byte[] mSendBuffer = new byte[length];
        mSendBuffer[0] = (byte) length;//数据长度
        mSendBuffer[2] = 0x00;//帧编号
        sendLen = 3;//起始位置
        System.arraycopy(data, 0, mSendBuffer, sendLen, size);
        //校验和计算,2+4+所有的数据，再取反
        byte check = (byte) (mSendBuffer[0] + mSendBuffer[2]);
        for (int i = 0; i < data.length; i++) {
            check += data[i];
        }
        mSendBuffer[1] = (byte) (-check);
        //到此得到完整的数据了

        //需要对数据进行RC4加密

        //数据长度那一位不参与加密
        byte[] tempBuffer = new byte[mSendBuffer.length - 1];
        System.arraycopy(mSendBuffer, 1, tempBuffer, 0, tempBuffer.length);
//        L.i("bryan", "RC4加密前>>>: " + HexUtil.encodeHexStr(tempBuffer));
        byte[] encData = Rc4.RC4Base(tempBuffer, Rc4.RC4Key);
//        L.i("bryan", "RC4加密后>>>: " + HexUtil.encodeHexStr(encData));
        //得到除了桢头的完整数据
        System.arraycopy(encData, 0, mSendBuffer, 1, encData.length);
        //拼接完整的数据
        byte[] resultBuffer = new byte[mSendBuffer.length + 2];
        resultBuffer[0] = FRAME_HEADER_CODE[0];
        resultBuffer[1] = FRAME_HEADER_CODE[1];
        sendLen = 2;//起始位置
        System.arraycopy(mSendBuffer, 0, resultBuffer, sendLen, mSendBuffer.length);
        L.i("bryan", "发送的完整数据>>>: " + HexUtil.encodeHexStr(resultBuffer));
        return resultBuffer;
    }
}
